package cn.itcast.service.impl;

import cn.itcast.exception.CustomException;
import cn.itcast.mapper.EmpExprMapper;
import cn.itcast.mapper.EmpLogMapper;
import cn.itcast.mapper.EmpMapper;
import cn.itcast.pojo.*;
import cn.itcast.service.DeptService;
import cn.itcast.service.EmpService;
import cn.itcast.utils.JwtUtils;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

@Service
@Slf4j
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpService {
    @Autowired
    private EmpMapper empMapper;
    @Autowired
    private DeptService deptService;
    @Autowired
    private EmpExprMapper empExprMapper;
    @Autowired
    private EmpLogMapper empLogMapper;
    @Autowired
    private JwtUtils jwtUtils;
    @Override
    public PageBean<Emp> findEmpByPage(Integer page, Integer pageSize,String name, Integer gender, LocalDate begin, LocalDate end) {

        //2.创建分页对象
        IPage<Emp> ipage = new Page<>(page, pageSize);
        //1.5 创建条件构造器
        LambdaQueryWrapper<Emp> wrapper= Wrappers.lambdaQuery();
        wrapper.like(!name.equals(""),Emp::getName,name)
                .eq(gender!=null,Emp::getGender,gender)
                .between(begin!=null && end!=null, Emp::getEntryDate,begin,end);
        //1.调用service的分页方法
        ipage = this.page(ipage,wrapper);
        List<Emp> records = ipage.getRecords();//获取当前页查询的集合数据
        Long total = ipage.getTotal();//获取总记录数
        //3.判断集合是否为空
        if (!CollectionUtils.isEmpty(records)) {
            //4.遍历拿到说有员工的部门id
            List<Integer> deptIds = records.stream().map(emp -> emp.getDeptId()).toList();
            //4.1部门id去重
            deptIds = deptIds.stream().distinct().toList();
            //根据部门id集合去查询所有的部门列表
            List<Dept> tbDepts = deptService.listByIds(deptIds);
            //双重for循环，实现为每一个emp实体对象中的deptName属性进行赋值
            records.forEach(emp -> {
                tbDepts.stream().filter(dept -> dept.getId().equals(emp.getDeptId()))
                        .findFirst()//返回值optional 这是一个容器对象
                        .ifPresent(dept -> emp.setDeptName(dept.getName()));//表示如果存在数据，则进行赋值
            });
            /*ArrayList<Integer> list = new ArrayList<>();
            for (Emp record : records) {
                Integer deptId = record.getDeptId();
                if (!list.contains(deptId)){
                    list.add(deptId);
                }
            }
            HashMap<Integer, String> deptNameMap = new HashMap<>();
            for (Integer i : list) {
                deptNameMap.put(i,tbDepts.stream().filter(dept -> dept.getId().equals(i)).findFirst().get().getName());
            }
            for (Emp record : records) {
                record.setDeptName(deptNameMap.get(record.getDeptId()));
            }*/

        }

        //3.将集合封装成pageBean对象返回给显示层
        PageBean<Emp> pageBean = new PageBean<>(total.intValue(), records);
        return pageBean;
    }
    /**
     * 添加员工
     * @param emp
     * @return
     */
    @Override
    public boolean add(Emp emp) {
        //数据校验操作
        /*if (emp.getUsername().length() < 6 || emp.getUsername().length() >10){
            throw new CustomException("用户名长度必须在6-10之间");
        }*/
        int isSuccess = 1;
        try {
            //1.补全emp的数据
            emp.setPassword("1234");
            emp.setCreateTime(LocalDate.now());
            emp.setUpdateTime(LocalDate.now());
            //2.先添加员工
            log.warn("添加员工之前的对象{}",emp);
            this.save(emp);
            log.warn("添加员工之后的对象{}",emp);
            //3.给员工设置id
            //4.添加工作经历
            List<EmpExpr> exprList = emp.getExprList();
            if (exprList != null && exprList.size() > 0) {
                exprList.forEach(expr -> expr.setEmpId(emp.getId()));
                empExprMapper.insert(exprList);
            }
            return true;
        } catch (Exception e) {
            isSuccess = 0;
            throw e;
        }finally {
            //保存操作日志
            EmpLog empLog = new EmpLog();
            empLog.setOperatorTime(LocalDateTime.now());
            empLog.setOperatorType(1);
            empLog.setBeforeOperatorData(null);
            String jsonObject = JSONObject.toJSONString(emp);
            empLog.setAfterOperatorData(jsonObject);
            empLog.setIsSuccess(isSuccess);
            log.warn("添加之后的数据是{}",jsonObject);
            empLogMapper.insert(empLog);
        }
    }

    /**
     * 根据id查询员工信息
     *
     * @param id 员工id
     * @return 查询到的员工信息
     */
    @Override
    public Emp findById(Integer id) {
        //1.根据ID查询员工数据
        Emp emp = this.getById(id);
        //2.根据主键Id查询工作经历集合
        List<EmpExpr> empExprs = empExprMapper.selectList(Wrappers.<EmpExpr>lambdaQuery().eq(EmpExpr::getEmpId, emp.getId()));
        //3.把工作经历集合封装到Emp实体对象中
        emp.setExprList(empExprs);
        //4.返回Emp实体对象
        return emp;
    }

    @Override
    public boolean update(Emp emp) {
        int isSuccess = 1;
        Emp beforeEmp = empMapper.findById(emp.getId());
        try {
            //修改员工
            emp.setUpdateTime(LocalDate.now());
            //1.根据主键id修改员工
            empMapper.updateById(emp);
            //2.根据主键id批量删除所有员工有关工作经历
            empExprMapper.delete(Wrappers.<EmpExpr>lambdaQuery().eq(EmpExpr::getEmpId,emp.getId()));
            //3.根据主键批量保存员工有关工作经历
            if (emp.getExprList() != null && emp.getExprList().size() > 0){
                //给所有员工有关工作经历设置员工id
                emp.getExprList().forEach(expr -> expr.setEmpId(emp.getId()));
                empExprMapper.insert(emp.getExprList());
            }
            return true;
        } catch (Exception e) {
            isSuccess = 0;
            throw e;
        }finally {
            //记录日志
            EmpLog empLog = new EmpLog();
            empLog.setOperatorTime(LocalDateTime.now());
            empLog.setOperatorType(3);
            empLog.setBeforeOperatorData(JSONObject.toJSONString(beforeEmp));
            empLog.setAfterOperatorData(JSONObject.toJSONString(emp));
            empLog.setIsSuccess(isSuccess);
            empLogMapper.insert(empLog);
        }

    }

    @Override
    public boolean deleteByIds(List<Integer> ids) {
        if (ids != null && ids.size() > 0){
            int isSuccess = 1;
            //先将要删除的员工的数据查询出来
            List<Emp> emps = empMapper.findByIds(ids);
            try {
                log.warn("要删除的id员工数据{}",emps);
                //删除员工
                this.removeByIds(ids);
                //删除所有员工有关工作经历
                empExprMapper.delete(Wrappers.<EmpExpr>lambdaQuery().in(EmpExpr::getEmpId,ids));
            } catch (Exception e) {
                isSuccess = 0;
                throw e;
            }finally {
                //记录日志
                EmpLog empLog = new EmpLog();
                empLog.setOperatorTime(LocalDateTime.now());
                empLog.setOperatorType(2);
                //将emps序列化json,保存
                String jsonObject = JSONObject.toJSONString(emps);
                empLog.setBeforeOperatorData(jsonObject);
                empLog.setAfterOperatorData(null);
                empLog.setIsSuccess(isSuccess);
                empLogMapper.insert(empLog);
            }
            return true;
        }
        return false;
    }





    /*@Autowired
    private EmpMapper empMapper;
    @Autowired
    private EmpExprMapper empExprMapper;
    @Autowired
    private EmpLogMapper empLogMapper;
    @Autowired
    private JwtUtils jwtUtils;
    @Override
    public PageBean<Emp> findByConditionAndPage(String name, Integer gender, LocalDate begin, LocalDate end, Integer page, Integer pageSize) {
        //1.开启分页助手,使用分页助手分页
        PageHelper.startPage(page, pageSize);
        //2.调用mapper查询
        List<Emp> byConditionAndPage = empMapper.findByConditionAndPage(name, gender, begin, end);
        Page<Emp> p = (Page<Emp>) byConditionAndPage;
        PageBean<Emp> pageBean = new PageBean<>((int) p.getTotal(), byConditionAndPage);
        return pageBean;
    }

    @Override
    public boolean add(Emp emp) {
        //数据校验操作
        if (emp.getUsername().length() < 6 || emp.getUsername().length() >10){
            throw new CustomException("用户名长度必须在6-10之间");
        }
        int isSuccess = 1;
        try {
            //1.补全emp的数据
            emp.setPassword("1234");
            emp.setCreateTime(LocalDate.now());
            emp.setUpdateTime(LocalDate.now());
            //2.先添加员工
            log.warn("添加员工之前的对象{}",emp);
            int row = empMapper.add(emp);
            log.warn("添加员工之后的对象{}",emp);
            //3.给员工设置id
            //4.添加工作经历
            List<EmpExpr> exprList = emp.getExprList();
            if (exprList != null && exprList.size() > 0) {
                exprList.forEach(expr -> expr.setEmpId(emp.getId()));
                empExprMapper.addBash(exprList);
            }
        } catch (Exception e) {
            isSuccess = 0;
            throw e;
        }finally {
            //保存操作日志
            EmpLog empLog = new EmpLog();
            empLog.setOperatorTime(LocalDateTime.now());
            empLog.setOperatorType(1);
            empLog.setBeforeOperatorData(null);
            String jsonObject = JSONObject.toJSONString(emp);
            empLog.setAfterOperatorData(jsonObject);
            empLog.setIsSuccess(isSuccess);
            log.warn("添加之后的数据是{}",jsonObject);
            empLogMapper.add(empLog);
        }
        return true;
    }

    @Override
    public Emp findById(Integer id) {
        Emp emp = empMapper.findById(id);
        return emp;
    }

    @Override
    public boolean update(Emp emp) {
        *//*int isSuccess = 1;
        Emp beforeEmp = empMapper.findById(emp.getId());
        try {
                //修改员工
                emp.setUpdateTime(LocalDate.now());
                empMapper.update(emp);
                //删除所有员工有关工作经历
                empExprMapper.deleteByEmpIds(List.of(emp.getId()));
                //添加所有员工有关工作经历
                if (emp.getExprList() != null && emp.getExprList().size() > 0){
                    //给所有员工有关工作经历设置员工id
                    em  p.getExprList().forEach(expr -> expr.setEmpId(emp.getId()));
                    empExprMapper.addBash(emp.getExprList());
                }
                return true;

        } catch (Exception e) {
            isSuccess = 0;
            throw e;
        }finally {
            //记录日志
            EmpLog empLog = new EmpLog();
            empLog.setOperatorTime(LocalDateTime.now());
            empLog.setOperatorType(3);
            empLog.setBeforeOperatorData(JSONObject.toJSONString(beforeEmp));
            empLog.setAfterOperatorData(JSONObject.toJSONString(emp));
            empLog.setIsSuccess(isSuccess);
            empLogMapper.add(empLog);
        }*//*
        return false;
    }

    @Override
    public boolean deleteByIds(List<Integer> ids) {
        if (ids != null && ids.size() > 0){
            *//*
            (1) 查询所有的满足的id员工
            (2) 查询所有的满足的工作经历
            (3) 在java中,遍历所有的员工, 去工作经历中找对应的工作经历然后放入到集合
            *//*
            int isSuccess = 1;
            //先将要删除的员工的数据查询出来
            List<Emp> emps = empMapper.findByIds(ids);
            try {
                log.warn("要删除的id员工数据{}",emps);
                //删除员工
                empMapper.deleteByIds(ids);
                //删除所有员工有关工作经历
                empExprMapper.deleteByEmpIds(ids);
            } catch (Exception e) {
                isSuccess = 0;
                throw e;
            }finally {
                //记录日志
                EmpLog empLog = new EmpLog();
                empLog.setOperatorTime(LocalDateTime.now());
                empLog.setOperatorType(2);
                //将emps序列化json,保存
                String jsonObject = JSONObject.toJSONString(emps);
                empLog.setBeforeOperatorData(jsonObject);
                empLog.setAfterOperatorData(null);
                empLog.setIsSuccess(isSuccess);
                empLogMapper.add(empLog);
            }
            return true;
        }
        return false;
    }

    @Override
    public List<EmpGender> empGenderData() {
        List<EmpGender> list = empMapper.empGenderData();
        return list;
    }

    @Override
    public JobDataBean empJobData() {
        List<CountEmpByJob> countEmpByJobs = empMapper.empJobData();
        JobDataBean jobDataBean = new JobDataBean();
        for (CountEmpByJob countEmpByJob : countEmpByJobs) {
            jobDataBean.getJobList().add(countEmpByJob.getJob());
            jobDataBean.getDataList().add(countEmpByJob.getCount());
        }
        return jobDataBean;
    }

    @Override
    public LogInfo login(String username, String password) {
        Emp loginEmp = empMapper.login(username, password);
        log.warn("登录信息{}",loginEmp);
        if (loginEmp == null){
            return null;
        }
        Map<String, Object> payload = new HashMap<>();
        payload.put("username",username);
        payload.put("id",loginEmp.getId());
        payload.put("name",loginEmp.getName());
        String jwt = jwtUtils.makeToken(payload, new Date(System.currentTimeMillis() + 1000L * 60 * 60 * 24));
        LogInfo logInfo = LogInfo.builder()
                .id(loginEmp.getId())
                .username(username)
                .name(loginEmp.getName())
                .token(jwt)
                .build();
        return logInfo;
    }

    @Override
    public List<Emp> findAllEmp() {
        List<Emp> emps = empMapper.findAllEmp();
        return emps;
    }*/
    @Override
    public LogInfo login(String username, String password) {
        Emp loginEmp = empMapper.login(username, password);
        log.warn("登录信息{}",loginEmp);
        if (loginEmp == null){
            return null;
        }
        Map<String, Object> payload = new HashMap<>();
        payload.put("username",username);
        payload.put("id",loginEmp.getId());
        payload.put("name",loginEmp.getName());
        String jwt = jwtUtils.makeToken(payload, new Date(System.currentTimeMillis() + 1000L * 60 * 60 * 24));
        LogInfo logInfo = LogInfo.builder()
                .id(loginEmp.getId())
                .username(username)
                .name(loginEmp.getName())
                .token(jwt)
                .build();
        return logInfo;
    }

    @Override
    public Set<String> findAllEmpImage() {
        Set<String> images = empMapper.findAllEmpImage();
        Set<String> processedImages = new HashSet<>();
        for (String image : images) {
            if (image != null && image.contains("/")) {
                // 截取最后一个"/"后面的部分
                String fileName = image.substring(image.lastIndexOf("/") + 1);
                processedImages.add(fileName);
            } else {
                processedImages.add(image);
            }
        }
        return processedImages;
    }
}
